package framework.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URLEncoder;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.SystemUtils;

/**
 * 项目名称：RenRenERP <br />
 * 类名称：NetworkUtils <br />
 * 创建人：Administrator <br />
 * 备注： <br />
 * 
 * @version <br />
 */
public class NetworkUtils
{
	/**
	 * 本机默认的IPv4地址
	 */
	public static final String LOCALHOST = "127.0.0.1";

	/**
	 * 本机默认的IPv6地址
	 */
	public static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";

	/**
	 * 获取项目的相对路径
	 */
	public static String getContextPath()
	{
		return getContextPath(SpringUtils.getRequest());
	}

	/**
	 * 获取项目的相对路径
	 */
	public static String getContextPath(HttpServletRequest request)
	{
		String contextPath = request.getContextPath();

		if (StringUtils.isNotEmpty(contextPath))
			contextPath = contextPath.replace("\\", "/");

		if (StringUtils.isNotEmpty(contextPath) && contextPath.endsWith("/"))
			contextPath = contextPath.substring(0, contextPath.length() - 1);

		return contextPath;
	}

	/**
	 * 下载文件
	 */
	public static void downloadFile(String fileName, HttpServletResponse response)
	{
		downloadFile(new File(fileName), response);
	}

	/**
	 * 下载文件
	 */
	public static void downloadFile(File file, HttpServletResponse response)
	{
		downloadFile(file, response, true);
	}

	/**
	 * 下载文件
	 */
	public static void downloadFile(File file, HttpServletResponse response, boolean setHeaderDownload)
	{
		if (setHeaderDownload)
			setHeaderDownload(response, file.getName());

		InputStream inputStream = null;
		OutputStream outputStream = null;

		try
		{
			inputStream = new FileInputStream(file);
			outputStream = response.getOutputStream();

			IOUtils.copy(inputStream, outputStream);
		}
		catch (Exception e)
		{
			System.err.println(e.getMessage());
		}
		finally
		{
			IOUtils.closeQuietly(inputStream);
			IOUtils.closeQuietly(outputStream);
		}
	}

	/**
	 * 设置HttpServletResponse头的下载信息
	 */
	public static void setHeaderDownload(HttpServletResponse response, String fileName)
	{
		response.setContentType("application/x-download");

		try
		{
			String contentDisposition = String.format("attachment; filename=\"%s\"", new String((fileName).getBytes("GBK"), "ISO8859-1"));
			response.setHeader("Content-Disposition", contentDisposition);
		}
		catch (Exception e)
		{
			System.err.println(e.getMessage());
		}
	}

	/**
	 * 设置HttpServletResponse头的图片信息
	 */
	public static void setHeaderImage(HttpServletResponse response)
	{
		response.setContentType("image/JPEG;charset=UTF-8");
	}

	/**
	 * 设置HttpServletResponse头的不缓存信息
	 */
	public static void setHeaderNoCache(HttpServletResponse response)
	{
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
	}

	/**
	 * 获取客户端IP地址
	 */
	public static String clientIp()
	{
		return clientIp(SpringUtils.getRequest());
	}

	/**
	 * 获取客户端IP地址
	 */
	public static String clientIp(HttpServletRequest request)
	{
		String head = request.getHeader("x-forwarded-for");
		if (StringUtils.isNotBlank(head) && !isUnknow(head))
			return head;

		head = request.getHeader("Proxy-Client-IP");
		if (StringUtils.isNotBlank(head) && !isUnknow(head))
			return head;

		head = request.getHeader("WL-Proxy-Client-IP");
		if (StringUtils.isNotBlank(head) && !isUnknow(head))
			return head;

		head = request.getHeader("HTTP_CLIENT_IP");
		if (StringUtils.isNotBlank(head) && !isUnknow(head))
			return head;

		head = request.getHeader("HTTP_X_FORWARDED_FOR");
		if (StringUtils.isNotBlank(head) && !isUnknow(head))
			return head;

		String remoteAddress = request.getRemoteAddr();
		if (StringUtils.equalsIgnoreCase(remoteAddress, LOCALHOST_IPV6))
			return localHostAddress();

		return remoteAddress;
	}

	/**
	 * 获取本地IP地址
	 */
	public static String localHostAddress()
	{
		try
		{
			// windows
			if (SystemUtils.IS_OS_WINDOWS)
			{
				InetAddress localhost = InetAddress.getLocalHost();
				return localhost.getHostAddress();
			}

			// linux
			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
			while (interfaces.hasMoreElements())
			{
				NetworkInterface networkInterface = interfaces.nextElement();
				if (!networkInterface.isLoopback() && !networkInterface.isVirtual() && networkInterface.isUp())
				{
					Enumeration<InetAddress> addressEnumeration = networkInterface.getInetAddresses();
					while (addressEnumeration.hasMoreElements())
					{
						InetAddress inetAddress = addressEnumeration.nextElement();
						String hostAddress = inetAddress.getHostAddress();
						if (!hostAddress.matches("^([0-9]{1,3}\\.){3}[0-9]{1,3}$"))
							continue;

						return hostAddress;
					}
				}
			}

			return "NONE";

		}
		catch (Exception e)
		{
			return "Exception";
		}
	}

	/**
	 * 获取本地Mac地址
	 */
	public static String localMacAddress()
	{
		try
		{
			InetAddress inetAddress = InetAddress.getLocalHost();
			byte[] macArray = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
			String macAddress = byteArrayToMacAddress(macArray);
			if (StringUtils.isNotEmpty(macAddress))
				return macAddress;

			Enumeration<NetworkInterface> interfaceEnumeration = NetworkInterface.getNetworkInterfaces();
			while (interfaceEnumeration.hasMoreElements())
			{
				byte[] array = interfaceEnumeration.nextElement().getHardwareAddress();
				if (ArrayUtils.isEmpty(array))
					continue;

				return byteArrayToMacAddress(array);
			}

			return StringUtils.EMPTY;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return StringUtils.EMPTY;
		}
	}
 

	public static String byteArrayToMacAddress(byte[] array)
	{
		return byteArrayToMacAddress(array, "-");
	}

	public static String byteArrayToMacAddress(byte[] array, String split)
	{
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < array.length; i++)
		{
			String hexString = Integer.toHexString(array[i] & 0xff);

			if (i > 0)
				stringBuffer.append(split);

			if (hexString.length() == 1)
				stringBuffer.append("0");

			stringBuffer.append(hexString);
		}

		return stringBuffer.toString().toUpperCase();
	}

	public static String concateUrlAndParam(String url, String key, String value)
	{
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(url);

		if (url!=null&&url.contains("?"))
			stringBuffer.append("&");
		else
			stringBuffer.append("?");

		stringBuffer.append(key);
		stringBuffer.append("=");
		stringBuffer.append(value);

		return stringBuffer.toString();
	}

	public static String encodeChinese(String url)
	{
		if (StringUtils.isEmpty(url) || !url.contains("?"))
			return url;

		int index = url.indexOf("?");
		String param = url.substring(index + 1);
		String[] array = StringUtils.split(param, "&");

		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(url.substring(0, index + 1));
		for (int i = 0; i < array.length; i++)
		{
			String[] pair = array[i].split("=");
			if (ArrayUtils.isEmpty(pair) || pair.length != 2)
				continue;

			String key = pair[0];
			String value = pair[1];

			stringBuffer.append(key);
			stringBuffer.append("=");
			if (value.matches("[\\u4E00-\\u9FA5]+"))
			{
				try
				{
					stringBuffer.append(URLEncoder.encode(value, "UFT-8"));
				}
				catch (Exception e)
				{
					e.printStackTrace();
					stringBuffer.append(value);
				}
			}
			else
			{
				stringBuffer.append(value);
			}

			stringBuffer.append("&");
		}

		return stringBuffer.toString();
	}

	/**
	 * 是否无法判断IP地址
	 */
	private static boolean isUnknow(String head)
	{
		return StringUtils.equalsIgnoreCase(head, "unknown");
	}
}
